<?php declare(strict_types=1);

namespace app\logic;
use app\exception\Failure;
use app\exception\ParamsInvalidate;
use app\exception\auth\UnassignedPermissions;
use app\exception\auth\UnassignedRoles;
use app\facade\model\AuthGroup as FaAuthGroupModel;
use app\facade\model\AuthRule as FaAuthRuleModel;
use app\facade\model\UserGroup as FaUserGroupModel;
use app\facade\model\AuthGroupAccess as FaAuthGroupAccessModel;
use app\library\Tree;
use think\facade\Db;
use think\model\Collection;

class Auth extends Base{

    // Check Auth
    public function checkAuth($path){
        //Check Post Url Exists
        $authRule = FaAuthRuleModel::where('post_url','=',$path)->field('rule_id,enabled')->find();
        if(empty($authRule)) {
            throw new ParamsInvalidate("request url invalidate");
        }
        // Disabled
        if($authRule['enabled']==0){
            throw new Failure('method disabled');
        }
        // Get User Rights Id Arr
        $userRightsIdArr = $this->getUserRightsArr();
        $ruleId = $authRule['rule_id'];
        if(!in_array($ruleId,$userRightsIdArr) && !$this->isSuper){
            return false;
        }
        return true;
    }

    private function getUserRightsArr(){
        // Get User Roles IDs
        $rolesIDs = $this->getUserRolesIDs();
        // Get Access Rules IDs
        $rightsIDs = $this->getRightsIDs($rolesIDs);
        return $rightsIDs;
    }


    public function getUserMenuRights($rightsIDs=[]){
        $isMenu = 1;
        // Rights Info
        if($this->isSuper){
            $rights = FaAuthRuleModel::where('is_menu','=',$isMenu)->select();
        }else{
            $rights = FaAuthRuleModel::whereIn('rule_id',$rightsIDs)->where('is_menu','=',$isMenu)->select();
        }

        foreach ($rights as &$right){
            $right->hidden(['create_at','update_at','enabled','delete_at']);
        }
        return $rights->toArray();
    }

    // Get User Btn Rights
    public function getUserBtnRights($rightsIDs = []){
        //
        $isMenu = 0;
        if($this->isSuper){
            $btnRights = FaAuthRuleModel::where('is_menu','=',$isMenu)->column('post_url');
        }else{
            $btnRights = FaAuthRuleModel::whereIn('rule_id',$rightsIDs)->where('is_menu','=',$isMenu)->column('post_url');
        }
        $newBtnRights = [];
        foreach ($btnRights as $right){
            $newBtnRights[]['post_url'] = $right;
        }
         return $newBtnRights;
    }

    public function getAllRights($rightsIDs = []){
        // Rights Info
        if($this->isSuper){
            $rights = FaAuthRuleModel::select();
        }else{
            $rights = FaAuthRuleModel::whereIn('rule_id',$rightsIDs)->select();
        }

        foreach ($rights as &$right){
            $right->hidden(['create_at','update_at','enabled','delete_at']);
        }
        return $rights->toArray();
    }


    //
    public function getUserRightsOfGroups(){
        // Get User Rights Arr
        $rightsIDs = $this->getUserRightsArr();
        $menuRights = $this->getUserMenuRights($rightsIDs);
        $btnRights = $this->getUserBtnRights($rightsIDs);
        $allRights = $this->getAllRights($rightsIDs);
        // var_dump($allRights);exit;
        $arr['all_rights'] = Tree::getTree($allRights);
        $arr['menu_rights'] = Tree::getTree($menuRights);
        $arr['btn_rights'] = $btnRights;
        return $arr;
    }

    // Get User Roles ID
    private function getUserRolesIDs() : array {
        $result = FaUserGroupModel::getUserGroupsByUserID($this->userId);
        if(empty($result))
            throw new UnassignedRoles();
        return $result;
    }
    // Get User Rights ID
    private function getRightsIDs(array $rolesIDs) : array {
        $result = FaAuthGroupAccessModel::getRightsIDs($rolesIDs);
        if(empty($result))
            throw new UnassignedPermissions();

        return $result;
    }

    // Save Auth Data
    public function saveAuth() : bool {
        $groupId = $this->request->param('group_id',0);
        $ruleIds = $this->request->param('rule_ids/a',[]);
        Db::startTrans();
        $delete = FaAuthGroupAccessModel::del($groupId);
        $newAuth = [];
        foreach ($ruleIds as $ruleId){
            $tmp['group_id'] = $groupId;
            $tmp['rule_id']= $ruleId;
            array_push($newAuth,$tmp);
        }
        $saveAll = [];
        if(!empty($newAuth)){
            $saveAll = FaAuthGroupAccessModel::insertAll($newAuth);
        }
        if($delete>=0 && !empty($saveAll)){
            Db::commit();
            return true;
        }else{
            Db::rollback();
            return false;
        }
    }

}